package com.jinzheng.qhnetty.util;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import lombok.extern.slf4j.Slf4j;

import java.util.List;


@Slf4j
public class GBT32960Decoder extends ByteToMessageDecoder {

    public static ByteBuf delimit = Unpooled.copiedBuffer(new byte[]{(byte) 0x23, (byte) 0x23});

    @Override
    public void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
        //获取开始的数据头数据位置
        int start = indexOf(in, 0, delimit);
        //缓冲区可读长度
        int len = in.readableBytes();
        if (start + 24 < len) {
            //数据单元长度
            int dataLen = in.getShort(in.readerIndex() + 22);
            if (len >= start + 25 + dataLen) {
                // 解决netty栈溢出问题
                ByteBuf buf = in.readRetainedSlice(start + 25 + dataLen);
                byte[] bytes = ByteBufUtil.getBytes(buf);
                buf.release();
                out.add(bytes);
            }
        }
    }


    /**
     * Returns the number of bytes between the readerIndex of the haystack and
     * the first needle found in the haystack.  -1 is returned if no needle is
     * found in the haystack.
     */
    public static int indexOf(ByteBuf haystack, int offset, ByteBuf needle) {
        for (int i = haystack.readerIndex() + offset; i < haystack.writerIndex(); i++) {
            int haystackIndex = i;
            int needleIndex;
            for (needleIndex = 0; needleIndex < needle.capacity(); needleIndex++) {
                if (haystack.getByte(haystackIndex) != needle.getByte(needleIndex)) {
                    break;
                } else {
                    haystackIndex++;
                    if (haystackIndex == haystack.writerIndex() &&
                            needleIndex != needle.capacity() - 1) {
                        return -1;
                    }
                }
            }

            if (needleIndex == needle.capacity()) {
                // Found the needle from the haystack!
                return i - haystack.readerIndex();
            }
        }
        return -1;
    }

}

